﻿import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)

# 数据
X = 2*np.random.rand(100,1)
y = 4+3*X+np.random.randn(100,1)
# 增加一列，用于求解偏置项b
X_b = np.c_[(np.ones((100,1)), X)]

# 测试（直接求解得到的回归方程）
X_new = np.array([[0],[2]])
# 增加一列，偏置项b（同求解时一样）
X_new_b = np.c_[(np.ones((2,1)), X_new)]


def plot_gradient_descent(theta,eta,theta_path=None):
    m = len(X_b)
    plt.plot(X,y,'b.')
    n_iterations = 1000
    for iteration in range(n_iterations):
        y_predict = X_new_b.dot(theta)
        plt.plot(X_new,y_predict,'b-')
        gradients = 2/m*X_b.T.dot(X_b.dot(theta) - y)
        theta = theta - eta*gradients
        if theta_path is not None:
            theta_path.append(theta)
    plt.xlabel('X_1')
    plt.axis([0,2,0,15])
    plt.title('eta = {}'.format(eta))


theta_path_bgd = []
np.random.seed(0)
theta = np.random.randn(2,1)
plt.figure(figsize=(10,4))
plt.subplot(131) # 1行3列的第1个
plot_gradient_descent(theta,eta=0.02)
plt.subplot(132) # 1行3列的第2个
plot_gradient_descent(theta,eta=0.1,theta_path=theta_path_bgd)
plt.subplot(133) # 1行3列的第3个
plot_gradient_descent(theta,eta=0.5)
plt.show()